' This is a sample GradeBook Program
' Run it from Console
' This program opens grade.txt file where the students' name and their grades are saved
' be sure to save the grade.txt file in the debug subfolder in your project
' Each line of grade.txt is in this format: eg: 'Simon Crown 78'
' Program will show the name and grades, Average grades, Maximum and Minimum grade
' It will also allow us to add additional name and grades
' Assumption one is Name has only first and last name.
' Second asumption is that put the cursor in the starting of a new line, otherwise it will write the new added line behind the existing last line.

Imports System.IO           ' This is for the console use

Module GradeBook

    Dim studentng As String                                                     'students name and grade

    ' Informations(): to show the options list to the user

    Sub Informations()
        Console.WriteLine("-----------------------------------------------------------------------------") 'Creates a line to make the program ordered
        Console.WriteLine("> Please choose one of the following options:")
        Console.WriteLine("-----------------------------------------------------------------------------")
        Console.WriteLine("")
        Console.WriteLine("Display Names and Grades(1)") ' Displays the options you have to choose to start the program
        Console.WriteLine("Display Just Names(2)")
        Console.WriteLine("Calculate Average (3)")
        Console.WriteLine("Maximum (4)")
        Console.WriteLine("Minimum (5)")
        Console.WriteLine("Draw Graph (6)")
        Console.WriteLine("Add Item (7)")
        Console.WriteLine("Quit (8)")

        Console.WriteLine("-----------------------------------------------------------------------------")
        Console.Write("Your option:" & "")                                      'uses write so that the number you put is on the same line as it
    End Sub

    ' The program starts from here

    Sub Main()

        Console.WriteLine(">Welcome to the Gradebook program!")

        Informations()                                          'tells user what to do

        Dim numre As Integer                                    'Number that is chosen

        Do
            Dim UserInput As String = Console.ReadLine
            If IsNumeric(UserInput) Then
                numre = CInt(UserInput)                      'Get the number until it is 8
                Select Case numre

                    Case 1
                        option1()                                   'Display Name and Grades
                    Case 2
                        option2()                                   'Display Name only
                    Case 3
                        option3()                                   'Display Calculated Average
                    Case 4
                        option4()                                   'Display Calculated Maximum
                    Case 5
                        option5()                                   'Display Calculated Minimum
                    Case 6
                        option6()                                   'Display Graph with Names
                    Case 7
                        option7()                                   'Add Item to text file
                    Case 8
                        option8()                                   'Quit Program

                End Select
            End If

            Informations()                                      ' Show the options list after each operation

        Loop Until numre = 8                                    'Quit the program if 8 chosen as well
    End Sub

    'Option1() shows all the students name and grades

    Sub option1()
        Dim sr As IO.StreamReader = IO.File.OpenText("grade.txt") 'Open the gradebook file
        Do While (sr.Peek <> -1)                                'Reads gradebook file line by line
            studentng = sr.ReadLine
            Console.WriteLine((studentng.Substring(0, studentng.Length - 3)) & ":" & (studentng.Substring(studentng.Length - 2, 2)))
            'Displays Name and Grade of Student
        Loop
        sr.Close()                                              'close the gradebook

    End Sub

    'Option2() shows all the students name only

    Sub option2()
        Dim sr As IO.StreamReader = IO.File.OpenText("grade.txt") 'Open the gradebook file
        Do While (sr.Peek <> -1)                                'Reads gradebook file line by line
            studentng = sr.ReadLine
            Console.WriteLine(studentng.Substring(0, studentng.Length - 3))
            'Displays only the names of the students
        Loop
        sr.Close()                                              'close the gradebook

    End Sub

    Sub option3()
        Dim sr As IO.StreamReader = IO.File.OpenText("grade.txt") 'Open the gradebook file
        Dim numstu As Double                                    ' Number of Students
        Dim avg As Double                                       ' average of grades
        Dim gr As Double = 0                                    ' make equal to 0 so that it will loop the value in the following code

        Do While (sr.Peek <> -1)                                 'read the grade.txt until the end

            studentng = sr.ReadLine
            gr += CDbl((studentng.Substring(studentng.Length - 2, 2))) 'adds all the grades
            numstu += 1                                         'adds the number of students
            avg = (CDbl(CDbl(gr) / numstu))                     'Adds all the grades and divides by total number of students

        Loop
        Console.WriteLine("The Average is:" & (CStr(Math.Round(avg, 2))) & "%") 'Rounds average to 2 decimal places and Displays it
        sr.Close()                                              'close the gradebook

    End Sub
    Sub option4()
        Dim sr As IO.StreamReader = IO.File.OpenText("grade.txt") 'Open the gradebook file
        Dim max As Double = -1                                  ' Max grade, Needs a low initial value so that it will switch it with the higher value
        Dim score As String
        Dim name As String = "temp"                             'Name of student, Need to give it an intial Value to switch with
        Do While (sr.Peek <> -1)                                'read the grade.txt until the end
            studentng = sr.ReadLine
            score = studentng
            If CDbl(score.Substring(score.Length - 2, 2)) > max Then 'Compares if the current number is larger then the current max
                max = CDbl(score.Substring(score.Length - 2, 2))    'if the current max is smaller than the current number, then the current number is the new max
                name = score.Substring(0, score.Length - 3)     'saves the name of the student
            End If
        Loop
        Console.WriteLine(name & " " & max)                     'displays the student with the max 
        sr.Close()                                              'close the gradebook

    End Sub
    Sub option5()
        Dim sr As IO.StreamReader = IO.File.OpenText("grade.txt") 'Open the gradebook file
        Dim min As Double = 101                                 ' Minimum Grade, Needs a high initial value so that it will switch it with the lower value
        Dim score As String                                     'grade of the student
        Dim name As String = "temp"                             'Needs an initial Value to switch with
        Do While (sr.Peek <> -1)                                'read the grade.txt until the end
            studentng = sr.ReadLine
            score = studentng
            If CDbl(score.Substring(score.Length - 2, 2)) < min Then 'Compares if the current number is smaller than the current minimum
                min = CDbl(score.Substring(score.Length - 2, 2)) 'if the current minimum is larger than the current number, then the current number is the new minimum
                name = score.Substring(0, score.Length - 3)     'Gets the name of the student with smallest grade
            End If
        Loop
        Console.WriteLine(name & " " & min)                     'Writes the name and the grade of the student with the lowest grade
        sr.Close()

    End Sub
    Sub option6()
        Dim sr As IO.StreamReader = IO.File.OpenText("grade.txt") 'Open the gradebook file
        Dim bar As String
        Dim student As String
        Do While (sr.Peek <> -1)
            student = sr.ReadLine
            bar = CStr((CDbl((student.Substring(student.Length - 2, 2))) / 10)) 'Gets the grade and divides by 10
            bar = CStr(Math.Round(CDbl(bar), 0))                'Rounds the grade to nearest whole number
            student = student.Substring(0, student.Length - 3)  'Gets students name
            Dim fmtStr As String = "{0,20}{1,-10}"              'Aligning the stars
            Select Case bar
                Case CStr(1)
                    Console.WriteLine(fmtStr, student & ":", "*") 'Displays name and the bar graph of the grade
                Case CStr(2)
                    Console.WriteLine(fmtStr, student & ":", "**")
                Case CStr(3)
                    Console.WriteLine(fmtStr, student & ":", "***")
                Case CStr(4)
                    Console.WriteLine(fmtStr, student & ":", "****")
                Case CStr(5)
                    Console.WriteLine(fmtStr, student & ":", "*****")
                Case CStr(6)
                    Console.WriteLine(fmtStr, student & ":", "******")
                Case CStr(7)
                    Console.WriteLine(fmtStr, student & ":", "*******")
                Case CStr(8)
                    Console.WriteLine(fmtStr, student & ":", "********")
                Case CStr(9)
                    Console.WriteLine(fmtStr, student & ":", "*********")
                Case CStr(10)
                    Console.WriteLine(fmtStr, student & ":", "**********")
            End Select
        Loop
        sr.Close()

    End Sub
    Sub option7()
        Dim name, grade As String
        Dim sw As New IO.StreamWriter("grade_new.txt", False) 'There is a True at the end so that it doesnt wipe the whole file then write
        Dim sr As New IO.StreamReader("grade.txt") 'There is a True at the end so that it doesnt wipe the whole file then write

        Do While (sr.Peek <> -1)
            'copy the file over to a new one
            sw.WriteLine(sr.ReadLine)
        Loop

        Console.Write("Name: ")                             'Asks for name
        name = Console.ReadLine()                           'Gets the name
        Console.Write("Grade: ")                            'Asks for Grade
        grade = Console.ReadLine()                          'Gets Grade
        sw.WriteLine(name & " " & grade)                    ' Writes name and grade to txt file
        sw.Close()                                          'Closes sw
        sr.Close()                                            'close sr
        System.IO.File.Delete("grade.txt")                  'delete the old file
        System.IO.File.Move("grade_new.txt", "grade.txt")   'rename the new file


    End Sub
    Sub option8()
        Exit Sub                                            'Exits the program

    End Sub
End Module
